package com.smartleanx.module.hrm.framework.operate.core.aop;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.smartleanx.framework.common.SystemConstants;
import com.smartleanx.framework.common.util.json.JsonUtils;
import com.smartleanx.framework.security.core.util.SecurityFrameworkUtils;
import com.smartleanx.module.hrm.context.EmployeeContextHolder;
import com.smartleanx.module.hrm.controller.admin.operationlog.vo.OperationLogSaveReqVO;
import com.smartleanx.module.hrm.framework.operate.core.annotations.OperationLog;

import com.smartleanx.module.hrm.intergration.AdminUserServiceProvider;
import com.smartleanx.module.hrm.service.operationlog.OperationLogService;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.Collections;
import java.util.Map;

/**
 * 订单的操作日志的记录 AOP
 *
 * @author tengcj
 * @since 2024/1/29
 */
@Component
@Aspect
@Slf4j
public class OperationLogAspect {
    /**
     * 用户编号
     */
    private static final ThreadLocal<Long> USER_CODE = new ThreadLocal<>();

    /**
     * 拓展参数 Map，用于格式化操作内容
     */
    private static final ThreadLocal<Map<String, Object>> EXTS = new ThreadLocal<>();

    @Resource
    private OperationLogService operationLogService;
    @Resource
    private AdminUserServiceProvider adminUserServiceProvider;

    @AfterReturning("@annotation(operationlog)")
    public void doAfterReturning(JoinPoint joinPoint, OperationLog operationlog) {
        try {
            // 1.1 操作用户
            // String userNickname = null;
            Long operator = SecurityFrameworkUtils.getLoginUserId();
            if (operator == null) {
                operator = SystemConstants.SYSTEM_USER_ID;
                // userNickname = SystemConstants.SYSTEM_USER_NICKNAME;
            }

            // 1.2 订单信息
            Map<String, Object> exts = ObjectUtil.defaultIfNull(EXTS.get(), Collections.emptyMap());
            String action = StrUtil.format(operationlog.operateType().getAction(), exts);
            // 2. 记录日志
            OperationLogSaveReqVO reqVO = new OperationLogSaveReqVO();
            reqVO.setOperator(operator.toString());
            reqVO.setDocType(operationlog.docType().getValue());
            reqVO.setCode(USER_CODE.get());
            reqVO.setOperateType(operationlog.operateType().getType());
            reqVO.setAction(action);
            operationLogService.createOperationLog(reqVO);

        } catch (Exception ex) {
            log.error("[doAfterReturning][OperateLog({}) 操作日志错误]", JsonUtils.toJsonString(operationlog), ex);
        } finally {
            clear();
        }
    }

    /**
     * 获得用户编号
     * <p>
     * 如果没有，则约定为 {@link SystemConstants#SYSTEM_USER_ID} 系统
     *
     * @return 用户类型
     */
    private static Long getUserId() {
        return EmployeeContextHolder.getEmployeeId();
    }

    public static void setOperationInfo(Long userCode, Map<String, Object> exts) {
        USER_CODE.set(userCode);
        // EXTRA.set(extra);
        EXTS.set(exts);
    }

    private static void clear() {
        USER_CODE.remove();
        // EXTRA.remove();
        EXTS.remove();
    }

}
